import { reactive, onMounted } from 'vue'

export default (selectorName: string) => {
  const draw = reactive<{
    canvasEl: HTMLCanvasElement | null
    ctx: CanvasRenderingContext2D | null
    canvasWidth: number
    canvasHeight: number
    animateList: { x: number; y: number }[]
  }>({
    canvasEl: null,
    ctx: null,
    canvasWidth: 400,
    canvasHeight: 400,
    animateList: [],
  })

  function init() {
    draw.canvasEl = document.querySelector(selectorName) as HTMLCanvasElement
    draw.ctx = draw.canvasEl.getContext('2d') as CanvasRenderingContext2D
    // draw.ctx.strokeStyle = '#ffffff'
    draw.ctx!.lineWidth = 2
    draw.ctx.lineJoin = 'round'
    draw.ctx.shadowColor = '#000'
    draw.ctx.shadowBlur = 4
    let isDrawing = false

    draw.canvasEl.onmousedown = () => {
      isDrawing = true
      draw.ctx!.beginPath()
    }
    draw.canvasEl.onmousemove = (e: MouseEvent) => {
      if (isDrawing) {
        const x = e.pageX - draw.canvasEl!.offsetLeft
        const y = e.pageY - draw.canvasEl!.offsetTop
        draw.animateList.push({
          x,
          y,
        })
        draw.ctx!.lineTo(x, y)
        draw.ctx!.stroke()
      }
    }
    draw.canvasEl.onmouseup = () => {
      isDrawing = false
      draw.animateList.push({
        x: -100,
        y: -100,
      })
    }

    draw.canvasEl.onmouseout = () => {
      const { canvasEl } = draw
      canvasEl.onmouseup()
    }
  }

  function clearCanvas() {
    draw.ctx!.clearRect(0, 0, draw.canvasWidth, draw.canvasHeight)
    draw.animateList = []
  }

  function previous() {
    draw.ctx!.clearRect(0, 0, draw.canvasWidth, draw.canvasHeight)

    draw.ctx?.beginPath()
    function test(fn: () => void, duration = 2000) {
      return new Promise((resolve) => {
        setTimeout(() => {
          fn()

          resolve(20)
        }, duration)
      })
    }

    draw.animateList.forEach(async (v) => {
      if (v.x === -100 && v.y === -100) {
        await test(() => {
          draw.ctx!.beginPath()
        })
      } else {
        await test(() => {
          draw.ctx?.lineTo(v.x, v.y)
          draw.ctx?.stroke()
        })
      }
    })
  }

  onMounted(() => {
    init()
  })
  return {
    init,
    previous,
    clearCanvas,
  }
}
